package top.linruchang.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import top.linruchang.enums.MyConstants;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Classname ReflectUtil
 * @Description
 * @Date 2020/9/5 16:37
 * @Created by lrc
 */
public class ReflectUtil {


    /**
     * <p>
     * description: Bean对象转换成Map对象 - 使用普通遍历循环
     * </p>
     *
     * @param bean 需要被解析的Bean对象
     * @return 返回 Bean的属性名，属性值的Map集合 - 属性值可为空
     **/
    public static Map<String, Object> parseBean2Map(Object bean) throws IllegalAccessException {

        Class<?> beanClazz = bean.getClass();
        Field[] beanDeclaredFields = beanClazz.getDeclaredFields();
        Map<String, Object> beanDeclaredFieldsMap = new HashMap<>();

        for (Field field : beanDeclaredFields) {
            field.setAccessible(true);
            beanDeclaredFieldsMap.put(field.getName(), field.get(bean));
        }

        return beanDeclaredFieldsMap;
    }

    /**
     * <p>
     * description: Bean对象转换成Map对象 - 使用stream流进行转换
     * </p>
     *
     * @param bean 需要转换成Map的对象
     * @return 返回 Bean的属性名，属性值的Map集合 - 属性值不为空 - stream流的要求
     **/
    public static Map<String, Object> parse2(Object bean) {

        Class<?> beanClazz = bean.getClass();
        Field[] beanDeclaredFields = beanClazz.getDeclaredFields();

        //先排除掉属性值是空的属性字段 - 在将其转换成Map对象
        Map<String, Object> beanDeclaredFieldsMap = Arrays.stream(beanDeclaredFields).filter(beanDeclaredField -> {
            try {
                beanDeclaredField.setAccessible(true);
                if (ObjectUtil.isEmpty(beanDeclaredField.get(bean))) {
                    return false;
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return true;
        }).collect(Collectors.toMap(Field::getName, beanDeclaredField -> {
            try {
                return beanDeclaredField.get(bean);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                return MyConstants.EMPTY_OBJ;
            }
        }));
        return beanDeclaredFieldsMap;
    }


    public static <T> List<T> translateList(List objs, Class<T> clazz) {
        List<T> convertList = new ArrayList<>();
        objs.forEach(obj -> {
            convertList.add(BeanUtil.toBean(obj, clazz));
        });
        return convertList;
    }


}
